/**
 * Copyright (c) 2011-2012
 * OmniCore CodeGuide
 */
package de.tum.in.oose.bumpers.ui;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.util.ArrayList;

import de.tum.in.oose.bumpers.cars.Car;
import de.tum.in.oose.bumpers.cars.SlowCar;
import de.tum.in.oose.bumpers.cars.UserCar;

/**
 * GameBoard UI.
 */
public final class GameBoard extends Canvas {

    private static final long serialVersionUID = 1L;
    private static GameBoard instance;
    private static int numberOfCars;
    private static int numberOfSlowCars = 1;

    private static Dimension defaultSize = new Dimension(500, 300);
    private static Color backgroundColor = Color.WHITE;

    private UserCar theDrivenCar;
    private ArrayList<Car> robotCars = new ArrayList<Car>();

    private String test = "None";

	private Image backgroundImage;
    private Graphics backgroundGraphics;
    private Dimension theSize;

    /**
     * @return GameBoard Singleton.
     */
    public static GameBoard getInstance() {
        if (instance == null) {
            instance = new GameBoard();
        }
        return instance;
    }

    private GameBoard() {
        setSize(getPreferredSize());
        theDrivenCar = new UserCar();
        theDrivenCar.setPosition(new Point(250, 30));

        GameBoard.numberOfCars = 0;
        
        new MouseSteering(this, theDrivenCar);

    }

    /**
     * @return Preferred Size
     */
    public Dimension getPreferredSize() {
        return defaultSize;
    }

    /**
     * @return all robot cars in an array
     */
    public Car[] getRobotCars() {
        return (Car[]) robotCars.toArray(new Car[robotCars.size()]);
    }

    /**
     * @return the car driven by the user
     */
    public UserCar getDrivenCar() {
        return this.theDrivenCar;
    }

    /**
     * updating the gameboard with graphics.
     * @param g the graphics to be updated.
     */
    public void update(Graphics g) {
        if (theSize == null || theSize.width != getSize().width
                || theSize.height != getSize().height) {
            theSize = getSize();

            backgroundImage = createImage(theSize.width, theSize.height);
            backgroundGraphics = backgroundImage.getGraphics();
        }
        paint(backgroundGraphics);
        g.drawImage(backgroundImage, 0, 0, null);
    }

    /**
     * @param g the graphics
     */
    public void paint(Graphics g) {

        g.setColor(backgroundColor);

        g.fillRect(0, 0, getSize().width, getSize().height);

        Car[] carArray = getRobotCars();
        int num = carArray.length;
        for (int i = 0; i < num; i++) {
            paintCar(carArray[i], g);

        }
        paintCar(theDrivenCar, g);
    }

    private void paintCar(Car car, Graphics g) {
        Point carPosition = car.getPosition();
        Point canvasPosition = convertPosition(carPosition);
        g.drawImage(car.getBody(), canvasPosition.x, canvasPosition.y, car
                .getSize().width, car.getSize().height, null);
    }

    /**
     * initalizer.
     */
    public void initiate() {
        theDrivenCar.initiate(getSize().width, getSize().height);
        SlowCar car = new SlowCar(getSize().width, getSize().height);
        SlowCar car2 = new SlowCar(getSize().width, getSize().height);
        this.robotCars.clear();
        car2.setPosition(new Point(0, 0));
        car2.setDirection(90);
        theDrivenCar.setSpeed(4);
        robotCars.add(car);
        robotCars.add(car2);
        ToolBar toolBar = ToolBar.getInstance();
        String test = toolBar.getTest();

        if (test.equals("Test1")) {
            theDrivenCar.setPosition(new Point(0, 150));
            car.setPosition(new Point(400, 150));
            car.setDirection(270);
        }
        if (test.equals("Test2")) {
            theDrivenCar.setPosition(new Point(100, 250));
            theDrivenCar.setDirection(135);
            theDrivenCar.setSpeed(7);
            car.setPosition(new Point(200, 150));
            car.setDirection(135);
        }
        if (test.equals("Test3")) {
            theDrivenCar.setPosition(new Point(400, 150));
            theDrivenCar.setDirection(270);
            car.setPosition(new Point(0, 150));
            car.setDirection(90);
        }

        repaint();
    }

    /**
     * @param toConvert the point to be converted.
     * @return the converted point
     */
    public Point convertPosition(Point toConvert) {
        return new Point(toConvert.x, getSize().height - toConvert.y);
    }



/**
 * @return the numberOfCars
 */
public static int getNumberOfCars() {
	return numberOfCars;
}

/**
 * @param numberOfCars the numberOfCars to set
 */
public static void setNumberOfCars(int numberOfCars) {
	GameBoard.numberOfCars = numberOfCars;
}

/**
 * @return the numberOfSlowCars
 */
public static int getNumberOfSlowCars() {
	return numberOfSlowCars;
}

/**
 * @param numberOfSlowCars the numberOfSlowCars to set
 */
public static void setNumberOfSlowCars(int numberOfSlowCars) {
	GameBoard.numberOfSlowCars = numberOfSlowCars;
}

/**
 * @return the test
 */
public String getTest() {
	return test;
}

/**
 * @param test the test to set
 */
public void setTest(String test) {
	this.test = test;
}
}

